#pragma once

#include "Singleton.h"

class Player;
class Item;

class LootMgr : public Singleton<LootMgr>
{
public:
	LootMgr();
	virtual ~LootMgr();

	bool LoadLootRelation();

	const LootSetPrototype* GetLootSetPrototype(uint32 lootSetID) const;

	bool IsPlayerRequireLoot4Quest(
		Player *pPlayer, uint32 lootSetID, uint32 questTypeID) const;

	LootPrizes GeneratePrizes(
		Player* pPlayer, uint32 lootSetID, uint32 questTypeID = 0) const;

	static void MergePrizes(LootPrizes& prizes, LootPrizes&& tempPrizes);
	static bool IsEmptyLootPrizes(const LootPrizes& prizes);

	static uint32 GetFillItemsLackSlotCount4LootItems(Player* pPlayer,
		const std::vector<LootItem>& lootItems, bool canMergeable = true);
	static void CreateAddItems4LootItems(
		Player* pPlayer, const std::vector<LootItem>& lootItems,
		ITEM_FLOW_TYPE flowType, params<uint32> flowParams, bool isSendPopMsg = false,
		Item** pNewItemPtr = NULL);

private:
	static void GenerateItemPrizes(Player* pPlayer, uint32 lootTimes,
		const std::vector<LootSetGroupItemPrototype>& lsgiList,
		std::vector<LootItem>& lootItems, uint32 questTypeID);
	static void GenerateChequePrizes(Player* pPlayer, uint32 lootTimes,
		const std::vector<LootSetGroupChequePrototype>& lsgcList,
		std::vector<LootCheque>& lootCheques);

	static uint32 CalcLootItemWeight(Player* pPlayer, uint32 questTypeID,
		const LootSetGroupItemPrototype& lsgiPt, uint32 lootedTimes,
		const std::vector<LootItem>& lootedItems);
	static LootItem NewLootItem(const LootSetGroupItemPrototype& lsgiPt);
	static void AppendLootItem(
		std::vector<LootItem>& lootItems, LootItem&& lootItem);
	static bool CanMergeLootItem(
		const LootItem& lootItem1, const LootItem& lootItem2);
	static uint32 GetLootedItemCount(
		const std::vector<LootItem>& lootedItems, uint32 itemTypeID);
	static bool CanLootItem4Player(Player* pPlayer, uint32 questTypeID,
		const LootSetGroupItem& lsgiInfo);

	static uint32 CalcLootChequeWeight(Player* pPlayer,
		const LootSetGroupChequePrototype& lsgcPt, uint32 lootedTimes);
	static LootCheque NewLootCheque(const LootSetGroupChequePrototype& lsgcPt);
	static void AppendLootCheque(
		std::vector<LootCheque>& lootCheques, LootCheque&& lootCheque);
	static bool CanMergeLootCheque(
		const LootCheque& lootCheque1, const LootCheque& lootCheque2);

	static inst_item_prop AssignLootItemProp(const LootItem& lootItem);

	std::unordered_map<uint32, LootSetPrototype> m_lsList;
};

#define sLootMgr (*LootMgr::instance())
